#include "VSDataBuffer.h"
#include "VSMath.h"
#include "VSVector3.h"
#include "VSVector2.h"
#include "VSVector3W.h"
#include "VSShaderStringFactory.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSDataBuffer,VSObject)
unsigned int VSDataBuffer::ms_uiDateTypeByte[DT_MAXNUM] =
{
	4,
	8,
	12,
	16,

	2,
	4,

	4,
	4,

	4,
	4,
	4,

	8,
	8,
	8,

	4,
	8,

	4
};
unsigned int VSDataBuffer::ms_uiDateTypeChannel[DT_MAXNUM] =
{
	1,
	2,
	3,
	4,

	1,
	1,

	4,
	4,
	
	2,
	2,
	2,

	4,
	4,
	4,

	2,
	4,

	4

};
static bool gs_bStreamRegistered_VSDataBuffer = VSDataBuffer::RegisterMainFactory();
bool VSDataBuffer::ms_bRegisterMainFactory = false;
bool VSDataBuffer::RegisterMainFactory()
{
	if (!ms_bRegisterMainFactory)
	{ 
		VSMain::AddInitialFuntion(VSDataBuffer::InitialClassFactory); 
		ms_bRegisterMainFactory = true;
	} 
	return ms_bRegisterMainFactory;

}

bool VSDataBuffer::InitialClassFactory()
{
	ms_ClassFactory.AddElement(ms_Type.GetName(),FactoryFunc);
	ms_ClassFactory.AddElement(_T("VSDateBuffer"),FactoryFunc);
	return 1;
}
VSObject * VSDataBuffer::FactoryFunc()
{
	return VS_NEW VSDataBuffer;

}
VSDataBuffer::VSDataBuffer()
{
	m_uiDT = DT_MAXNUM;

	m_uiNum = 0;
	m_pDate = NULL;

}
VSDataBuffer::~VSDataBuffer()
{
	VSMAC_DELETEA(m_pDate);
}
unsigned int VSDataBuffer::DiskUse()const
{
	unsigned int Used = VSObject::DiskUse();
	Used += sizeof(unsigned int) * 2;
	Used += GetSize();

	return Used;
}

bool VSDataBuffer::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSObject::Save(rStream,iSaveUse))
		return 0;

	if(!m_uiNum || !m_pDate)
		return 0;

	if(!rStream.Write(&m_uiDT,sizeof(unsigned int)))
		return 0;
	iSaveUse +=sizeof(unsigned int);
	

	if(!rStream.Write(&m_uiNum,sizeof(unsigned int)))
		return 0;

	iSaveUse +=sizeof(unsigned int);

	
	if(!rStream.Write(m_pDate,GetSize()))
		return 0;
	iSaveUse += GetSize();

	return 1;
}
bool VSDataBuffer::Load(VSStream & rStream,unsigned int &iSaveUse)
{
	if(!VSObject::Load(rStream,iSaveUse))
		return 0;
	if(!rStream.Read(&m_uiDT,sizeof(unsigned int)))
		return 0;
	iSaveUse +=sizeof(unsigned int);
	if(!rStream.Read(&m_uiNum,sizeof(unsigned int)))
		return 0;
	iSaveUse +=sizeof(unsigned int);
	
	if(!m_uiNum)
		return 0;

	VSMAC_DELETEA(m_pDate);

	m_pDate = VS_NEW unsigned char[GetSize()];

	if(!m_pDate)
		return 0;

	if(!rStream.Read(m_pDate,GetSize()))
		return 0;

	iSaveUse +=GetSize();

	return 1;
}

bool VSDataBuffer::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSDataBuffer* Temp = DynamicCast<VSDataBuffer>(pObject); 
	if(!Temp)
		return 0;
	if(!Temp->m_pDate)
		return 0;
	if(VSObject::Clone(pObject,uiType))
	{
		
		
		m_uiNum		= Temp->m_uiNum;
		m_uiDT		= Temp->m_uiDT;

		VSMAC_DELETEA(m_pDate);

		m_pDate = VS_NEW unsigned char[GetSize()];

		if(!m_pDate)
			return 0;
		VSMemcpy(m_pDate,Temp->m_pDate,GetSize());

		return 1;	
	}
	else
		return 0;
}
bool VSDataBuffer::SetDate(const void *pDate,unsigned int uiNum,unsigned int uiDT)
{
	if(uiDT >= DT_MAXNUM || !pDate || !uiNum)
		return 0;

	m_uiDT = uiDT;
	m_uiNum = uiNum;

	VSMAC_DELETEA(m_pDate);

	m_pDate = VS_NEW unsigned char[GetSize()];

	if(!m_pDate)
		return 0;
	VSMemcpy(m_pDate,pDate,GetSize());
	return 1;
}
bool VSDataBuffer::AddDate(const void *pDate,unsigned int uiNum,unsigned int uiDT)
{
	if(uiDT >= DT_MAXNUM || !pDate || !uiNum)
		return 0;
	if(m_uiDT != VSMAX_INTEGER && m_uiDT != uiDT)
		return 0;


	unsigned char * Temp = NULL;
	Temp = VS_NEW unsigned char[ ( uiNum + m_uiNum )* GetStride()];
	if(!Temp)
		return 0;
	VSMemcpy(Temp,m_pDate,GetStride() * m_uiNum);
	VSMemcpy(Temp + GetStride() * m_uiNum,pDate,GetStride() * uiNum);

	VSMAC_DELETEA(m_pDate);
	m_uiNum += uiNum;
	m_pDate =(void *)Temp;
	return 1;
}
bool VSDataBuffer::CreateEmptyBuffer(unsigned int uiNum,unsigned int uiDT)
{
	if(uiDT >= DT_MAXNUM || !uiNum)
		return 0;

	m_uiDT = uiDT;
	m_uiNum = uiNum;
	VSMAC_DELETEA(m_pDate);

	m_pDate = VS_NEW unsigned char[GetSize()];

	if(!m_pDate)
		return 0;
	VSMemset(m_pDate,0,GetSize());
	return 1;
}



